/*
 * Copyright (C) 2010, Funcom AS, All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  @authors
 *  Svein Gunnar Larsen <sveingunnarlarsen@gmail.com>
 *  Erik Thune Lund <culex.eriklund@gmail.com>
 *  Michel Krohn-Dale <kronicz@gmail.com>
 */

package com.funcom.peeler;

import com.funcom.peeler.symbol.Symbol;
import com.jmex.bui.BCursor;
import com.jmex.bui.BImage;
import com.jmex.bui.provider.DefaultResourceProvider;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

/**
 * Resourceloader for the editor
 */
public class ResourceLoader extends DefaultResourceProvider {

    private Map< PeelStyleSheet, String > stylesheet_to_path = new HashMap< PeelStyleSheet, String >();

    // Various images for our toolbox;
    private ImageIcon select, mark, pan, resize, newWork, save, load;

    private static ResourceLoader ourInstance = new ResourceLoader();

    // Used to check when a file was last modified so we don't use the cache when the file has been modified.
    private Map< String, Long > fileModified = new HashMap< String, Long >();

    public static ResourceLoader getInstance() {
        return ourInstance;
    }

    public PeelStyleSheet loadStyleSheetFromFile( String filename ) {

        try {
            PeelStyleSheet stylesheet = new PeelStyleSheet( new FileReader( filename) , this );
            return stylesheet;
        }
        catch ( FileNotFoundException e ) {
            return null;
        }
    }

    public PeelStyleSheet loadStyleSheetFromResource( String filename ) {

        try {
            InputStream input = ResourceLoader.class.getResourceAsStream( filename );
            InputStreamReader reader = new InputStreamReader( input );
            PeelStyleSheet stylesheet = new PeelStyleSheet( reader, this );
            return stylesheet;
        }
        catch ( Exception e ) {
            return null;
        }
    }

    public PeelStyleSheet loadStyleSheet( String filename ) {

        // Try file and resource loading before failing
        PeelStyleSheet stylesheet = loadStyleSheetFromFile( filename );

        if ( stylesheet == null ) {
            loadStyleSheetFromResource( filename );
        }

        // Both methods failed
        if ( stylesheet == null ) {
            //throw new NullPointerException( "Cannot load stylesheet: " + filename );
            return null;
        }

        // This one is good, it can be mapped
        stylesheet_to_path.put( stylesheet, filename );

        return stylesheet;
    }

    public String getStyleSheetPath( PeelStyleSheet stylesheet ) {
        return stylesheet_to_path.get( stylesheet );
    }

    public BImage loadImage(String path) throws IOException {

        // normalize the image path
    	String newPath = path;
        if (!newPath.startsWith("/")) {
            newPath = "/" + newPath;
        }

        File temp = new File( path );

        if (temp.exists() && fileModified.containsKey( path )) {
            long timeStamp = temp.lastModified();

            if (timeStamp > fileModified.get( path )) {
                _cache.remove( newPath );
                fileModified.put( path, timeStamp);
            }
        }

        BImage image = super.loadImage( path );
        if ( image != null && !fileModified.containsKey( path ) )
            fileModified.put( path, temp.lastModified() );
        return image;
        /*



        URL url = getClass().getResource( newPath );

        if (url == null) {

        }







        // first check the cache
        WeakReference<BImage> iref = _cache.get(newPath);
        BImage image;

        if (iref != null && (image = iref.get()) != null) {
            long lastMod = new File( path ).lastModified();
            if ( fileModified.containsKey( path ) && lastMod > fileModified.get( path )) {
                fileModified.put( path, lastMod );
            } else {
                return image;
            }
        }

        // create and cache a new BUI image with the appropriate data
        URL url = getClass().getResource(newPath);
        if (url == null) {
        	File file = new File(path);
            fileModified.put( path, file.lastModified() );
            url = file.toURI().toURL();
        	if (url == null) {
        		throw new IOException("Can't locate image '" + newPath + "'.");
        	}
        }
        image = new BImage(url);
        _cache.put(newPath, new WeakReference<BImage>(image));

        return image;

        return super.loadImage( path );


        */
    }

    private ResourceLoader() {

            select      = new ImageIcon("resources/select.png");
            mark        = new ImageIcon("resources/mark.png");
            pan         = new ImageIcon("resources/pan.png");
            resize      = new ImageIcon("resources/resize.png");
            newWork     = new ImageIcon("resources/new.png");
            save        = new ImageIcon("resources/save.png");
            load        = new ImageIcon("resources/load.png");

    }

    public PeelStyleSheet getDefaultWorkBenchStyle() {
        return loadStyleSheet( "resources/workBenchStyle.bss" );
    }

    public ImageIcon getImageIcon(int index) {

        switch (index) {
            case Symbol.ToolImage.SELECT:
                return select;
            case Symbol.ToolImage.MARK:
                return mark;
            case Symbol.ToolImage.PAN:
                return pan;
            case Symbol.ToolImage.RESIZE:
                return resize;
            case Symbol.ToolImage.NEW:
                return newWork;
            case Symbol.ToolImage.SAVE:
                return save;
            case Symbol.ToolImage.LOAD:
                return load;
            default:
                return null;
       }
    }

}

